package com.kancy.stream.rabbit.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

/**
 * AbstractRabbitService
 *
 * spring.rabbitmq.publisher-confirms=true
 * spring.rabbitmq.publisher-returns=true
 * spring.rabbitmq.template.mandatory=true
 *
 * @author kancy
 * @date 2020/3/7 22:20
 */
public abstract class AbstractRabbitService implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
    private static Logger log = LoggerFactory.getLogger(AbstractRabbitService.class);

    protected final RabbitTemplate rabbitTemplate;

    public AbstractRabbitService(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 消息确认
     * spring.rabbitmq.publisher-confirms=true
     *
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            log.info("消息[{}]发送成功!" , correlationData);
        } else {
            log.info("消息[{}]发送失败: {}" , correlationData, cause);
        }
    }

    /**
     * 消息返回
     *
     * mandatory标志告诉服务器至少将该消息route到一个队列中，否则将消息返还给生产者；
     * spring.rabbitmq.template.mandatory=true
     *
     * immediate标志告诉服务器如果该消息关联的queue上有消费者，则马上将消息投递给它，
     * 如果所有queue都没有消费者，直接把消息返还给生产者，不用将消息入队列等待消费者了；
     *
     * @param message
     * @param replyCode
     * @param replyText
     * @param exchange
     * @param routingKey
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.info("退回的消息，replyCode ：{}, replyText:{}, exchange: {} , routingKey: {} , header: {}",
                replyCode, replyText, exchange, routingKey, message.getMessageProperties().getHeaders());
    }
}
